﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mapbox.Unity.Map;
using Mapbox.Utils;

public class GPS : MonoBehaviour
{
    private Vector2d coordinate;
    private AbstractMap map;
    private Guide guide;
    private float timeStep;
    private RouteCache routeCache;

    private RouteCache RouteCache
    {
        get
        {
            if (routeCache == null)
            {
                routeCache = GetComponent<RouteCache>();
            }
            return routeCache;
        }
    }

    public Vector2d Coordinate {
        get
        {
            return coordinate;
        }
        private set
        {
            coordinate = value;
        }
    }

    private bool initializated;

    void Start()
    {
        timeStep = 0;
        guide = FindObjectOfType<Guide>();
        map = GetComponent<AbstractMap>();
        StartPositioning();

        var visualizer = map.MapVisualizer;
        visualizer.OnMapVisualizerStateChanged += UpdateMap;

        initializated = false;
    }

    private void UpdateMap(ModuleState state)
    {
        if(state == ModuleState.Finished)
        {
            map.Initialize(coordinate, 16);
            var visualizer = map.MapVisualizer;
            visualizer.OnMapVisualizerStateChanged -= UpdateMap;
        }
    }

    public void BackToSelf()
    {
        FindObjectOfType<Mapbox.Examples.CameraMovement>().ResetPosition(guide.SelfPos);
    }

    public void StartPositioning()
    {
        Input.location.Start(10.0f, 10.0f);
        SetCoordinate(Input.location.lastData.latitude, Input.location.lastData.longitude);
    }

    private void SetCoordinate(double latitude,double longitude)
    {
        Coordinate = new Mapbox.Utils.Vector2d(latitude, longitude);
    }

#if !UNITY_EDITOR
    private void FixedUpdate()
    {
        timeStep++;

        if(timeStep >= 10)
        {
            SetCoordinate(Input.location.lastData.latitude, Input.location.lastData.longitude);
            guide.SetSelfPoint(map.GeoToWorldPosition(coordinate));
            timeStep = 0;
            if (RouteCache != null && initializated)
            {
                RouteCache.UpdateCache(Coordinate);
            }
            else if(!initializated)
            {
                initializated = true;
            }
        }
    }
#elif UNITY_EDITOR
    private void FixedUpdate()
    {
        timeStep++;

        if (timeStep >= 1)
        {
            Vector2d geo = map.WorldToGeoPosition(guide.SelfPos);
            SetCoordinate(geo.x, geo.y);
            timeStep = 0;
            if (RouteCache != null && initializated)
            {
                RouteCache.UpdateCache(Coordinate);
            }
            else if(!initializated)
            {
                initializated = true;
            }
        }
    }
#endif

public void StopPositioning()
    {
        Input.location.Stop();
    }
}
